<?php  if (!defined('APPPATH')) exit('No direct script access allowed');

session_start();

/**
* @Author: Darius Kasperavicius
* @Email: damdam@bk.ru
*	www.tinkama.lt
*
* Inspired by : Dean Ericson
* 
*/


class breadcrumbs
{


	var $breadcrumbs = array();

	/**
     *  Are we using smart breadcrumbs?
     *  This removes browsing history Auto -> Fruits -> Apple -> Tractor
     *  And creates  Auto -> Tractor
     * 
     *  @return void
     */
	var $enable_smart_breadcrumbs = true;

	/**
     *  Do we fill a gaps in breadcrumbs?
     *  This will create from:
     *  Transport ->  Tractor
     * 
     *  this:
     *  Transport -> Auto ->  Tractor
     * 
     *  @return void
     */

	var $fill_missing_breadcrumbs = true;

	/**
	 * we can assign manualy breadcrum level, and do not use routes
	 * In this case we add
	 *  $bc = array(
               'title' => 'Breadcrum title',
               'url' => 'path/',
               'level' => '3',
	        );
	     REMEMBER, WE STILL NEED var $routes DEFINED!
	 *
	 */
	
	var $define_level_manually  = false;
	
	/**
     *  We need to fill routes by witch we will create a levels
     *  
     *  [level] => array('[route]', '[model_method]', '[method execution order]')
     * 
     *  @return void
     */

	var $routes = array(
		0 => array('lyrics', 'index', 0), //assign to array. this for future models
		1 => array('lyrics/artists/', 'artists', 1, true),
		2 => array('lyrics/artists/term/(:any)', 'letter', 3),
		3 => array('lyrics/songs/(:num)', 'artist', 2),
		4 => array('lyrics/(:num)/(:any)', 'lyrics', 4),
	);


	/**
     *  Do the use model methods execution order?
     *  
     *  @return void
     */


	var $use_methods_order = true;

	
	/**
     *  Enable errors on missing breadcrumbs, else we show nothing, breadcrum is skipped
     *  
     *  @return void
     */
	var $show_error_on_missing_letter = true;
	
	
	var $delimiter = '&raquo;';
	
	
	
	
	
	
	
	
	/**
     *  Constructor of the class
     *
     *  Creates a new instance of the class and initialize some properties
     *
     *  @return void
     */
	
	function breadcrumbs()
	{
		$this->CI =& get_instance();
		$this->get_config();

		$this->get_breadcrumbs();

	}

	function get_config() {
		
		if (empty($this->routes)) $this->routes = $this->CI->config->item ('breadcrumbs_routes');
		
	}
	
	function add($bc)
	{

		if ($bc['isRoot']) {
			$this->reset();
		}

		if(in_array($bc, $this->breadcrumbs))
		{

			// in array, remove objects after index
			$index = array_search($bc,$this->breadcrumbs);

			for($i=(count($this->breadcrumbs)-1); $i>=($index+1); $i-- )
			{
				unset($this->breadcrumbs[$i]);
			}
		}
		else
		{
			// add the new entry
			$this->breadcrumbs[] = $bc;
		}
		$this->save_breadcrumbs();

	}


	function save_breadcrumbs() {
		$_SESSION['breadcrumbs'] = $this->breadcrumbs;
	}


	function get_breadcrumbs () {
		$this->breadcrumbs = $_SESSION['breadcrumbs'];
	}


	function reset(){
		unset($this->breadcrumbs);
		unset($_SESSION['breadcrumbs']);
		$this->breadcrumbs = array();
	}


	/**
     *  Renders the breadcrumb
     *
     */
	function render($bc = '', $data = '')
	{

		if ($bc) 
		{
			$this->add($bc);
		}
		
		$return_str='';

		
		//$this->CI->load->model('breadcrumb_model');
		$this->CI->load->module_model('lyrics', 'breadcrumb_model', 'breadcrumb_model');

		$this->CI->breadcrumb_model->set_data($data);

		$breadcrumbs = $this->breadcrumbs;

		if ($this->enable_smart_breadcrumbs)
		{
			$breadcrumbs = $this->smart_breadcrumbs($breadcrumbs);
		}

		$i=1;
		foreach($breadcrumbs as $bc)
		{
			$delimiter = $i < count($breadcrumbs)?$this->delimiter:'';

			if($i < count($breadcrumbs))
			{
				$return_str .= anchor($bc['url'],$bc['title'], array('class'=>'activebreadcrumbs')).' '.$delimiter;
			}
			else
			{
				$return_str .= "<span class=\"nonActivebreadcrumbs\">".$bc['title'].'</span> '.$delimiter;
			}
			$i++;
		}

		return $return_str;
	}


	function  smart_breadcrumbs($breadcrumbs) {



		$last_breadcrumb_level =  $this->get_level(end($breadcrumbs));

		foreach ($breadcrumbs as $breadcrumb)
		{
			$level = $this->get_level($breadcrumb);

			if ($level === 0 or $level)
			{
				$leveled_breadcrumbs[$level] = $breadcrumb;

			}
		}

		if ($this->fill_missing_breadcrumbs)
		{
			$leveled_breadcrumbs = $this->add_missing_routes($leveled_breadcrumbs, $last_breadcrumb_level);
		}

		ksort($leveled_breadcrumbs);

		//we show only from last breadcrumb press
		//this is it avoid Fruits -> Car (after pressing Fruit in Transport -> Car)
		$slice_to = $last_breadcrumb_level + 1;
		if ($last_breadcrumb_level > 0)
		$leveled_breadcrumbs = array_slice($leveled_breadcrumbs, 0, $slice_to);

		return $leveled_breadcrumbs;

	}




	function add_missing_routes ($leveled_breadcrumbs, $last_breadcrumb_level) {

		//get all levels we have
		$actual_keys = array_keys($leveled_breadcrumbs);
		$ideal_keys = array_keys($this->routes);
		$missing_keys = array_diff($ideal_keys, $actual_keys );

		$this->CI->breadcrumb_model->set_type($this->routes[$last_breadcrumb_level][1]);

		for ($i = 0; $i <= $last_breadcrumb_level; $i++)
		{

			if (array_key_exists($i, $missing_keys))
			{
				$method = $this->routes[$i][1];
				$order_num = $this->routes[$i][2];
				$is_method_common = $this->routes[$i][3];

				if($this->use_methods_order)
				{
					//save $i to preserve order
					$methods[ $order_num ] = array($i, $method, $is_method_common);
				}
				else
				{
					
					$result = $this->CI->breadcrumb_model->get_data($method, $this->routes[$last_breadcrumb_level][1], $is_method_common);
					if ($result)
					{
						//$result = $this->CreateBreadCrumb($result, $key);
						$full_array[$i] = $result;
					}
				}

			}
			else
			{
				$full_array[$i] = $leveled_breadcrumbs[$i];
			}
		}

		
		/**
		 * If we are using methods order, execute them by order
		 */

		if($this->use_methods_order && is_array($methods))
		{
			ksort($methods);

			foreach ($methods as  $exec_method)
			{
				//echo "ask get_" . $exec_method[1] . '_from_' . $this->routes[$last_breadcrumb_level][1] . '<br/>';
				$result = $this->CI->breadcrumb_model->get_data($exec_method[1], $this->routes[$last_breadcrumb_level][1], $exec_method[2]);
				if ($result)
				{
					$full_array[$exec_method[0]] = $result;
				}
				elseif($this->show_error_on_missing_letter) 
				{
					show_error('No data from breadcrumb_model->get_' . $exec_method[1] . '_from_' . $this->routes[$last_breadcrumb_level][1] . '()');
				}
			}
		}

		return $full_array;
	}


	function  get_level ($breadcrumb) {

		if ($this->define_level_manually) {
			return ($breadcrumb['level']) ? $breadcrumb['level'] : false;
		}
		else {
			foreach ($this->routes as $key => $array)
			{
				//$key = level
				//$val = defined routes
				$val = $array[0];
				// Convert wild-cards to RegEx
				$val = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $val));
	
				// Does the RegEx match?
				if (preg_match('#^'.$val.'$#', $breadcrumb['url']))
				{
					return $key;
				}
			}
			return false;
		}
	}

	/**
     *  Remove an entry from the breadcrumb by specifying a title to remove
     *
     *  @param  string  $title  Title to remove from the breadcrumb
     *
     *  @return void
     *
     */
	function remove_by_title($title)
	{

		// iterate through the existing breadcrumbs entries
		foreach ($this->breadcrumbs as $key=>$values) {

			// if a breadcrumb is found having the sought title
			if ($values["title"] == $title) {

				// remove it
				unset($this->breadcrumbs[$key]);
			}
		}
	}

	/**
     *  Remove an entry from the breadcrumb by specifying an url to remove
     *
     *  @param  string  $url    URL to remove from the breadcrumb
     *
     *  @return void
     *
     */
	function remove_by_url($url)
	{

		// iterate through the existing breadcrumbs entries
		foreach ($this->breadcrumbs as $key=>$values) {

			// if a breadcrumb is found having the sought url
			if ($values["url"] == $url) {

				// remove it
				unset($this->breadcrumbs[$key]);
			}
		}
	}

}

?>
